package com.gopay.checkorder.service.impl;

import java.math.BigDecimal;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.checkorder.service.BankOrderService;
import com.gopay.checkorder.service.task.BankCountDownLatch;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.bank.PabConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.dayend.BaseDayendEntry;
import com.gopay.common.domain.bank.pab.ebank.PabB2bMessage;
import com.gopay.common.domain.bank.pab.ebank.PabOrderMessageRes;
import com.gopay.common.domain.bank.pab.ebank.PabQueryOrdersMessageRes;
import com.gopay.common.domain.cashier.BankCardType;
import com.gopay.common.domain.cps.vo.CheckOrderResult;
import com.gopay.common.domain.cps.vo.InAccInfo;
import com.gopay.common.util.DateUtils;
import com.gopay.remote.bank.BankInteractRemoteService;

public class CheckOrderPabB2bImpl implements BankOrderService {
	private final static Logger logger = LoggerFactory.getLogger("PAB");

	@Resource(name = "bankClient")
	private BankInteractRemoteService bankClient;
	@SuppressWarnings("rawtypes")
	@Override
	public CheckOrderResult checkOrder(BankOrder bankOrder, String target) {
		CheckOrderResult checkOrderResult = new CheckOrderResult();
		checkOrderResult.setSuccess(false);
		checkOrderResult.setOrderId(bankOrder.getOrderId());
		try {

			PabB2bMessage base = new PabB2bMessage();
			base.setOrderId(bankOrder.getOrderId());
			base.setBankOrderId(bankOrder.getOutOrderId());
			base.setOrderDate(DateUtils.format(bankOrder.getSendBankTm(),"yyyyMMddHHmmss"));
			base.setBank(BankConstants.BANK_LOGO_PAB);
			base.setBankIntrChann(BisBankInterfaceChannel.get(bankOrder.getInterfaceChennelCode()));
			base.setBankBusProd(BisBankBusinessProd.get(bankOrder.getBankBizProdCode()));
			Result result = new Result();

			result = bankClient.query(base);

			if (result == null || !result.isSuccess()) {
				logger.error("bankClient fail.");
				if(result ==null || ProcCodeConstants.PROC_CODE_100E6037.equals(result.getResultCode())){
					BankCountDownLatch.failIncrease(bankOrder.getBankCode());
					checkOrderResult.setCommunicateError(true);
				}
				logger.error(ToStringBuilder.reflectionToString(result,ToStringStyle.DEFAULT_STYLE));
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
				checkOrderResult.setErrMsg("系统返回对账结果为空");
				return checkOrderResult;
			}
			// 获取订单清单交易的申请数据的数据类
			PabQueryOrdersMessageRes response = null;
			if (result != null && result.isSuccess()) {
				response = (PabQueryOrdersMessageRes) result.getDefaultModel();
			}
			if (response == null) {
				logger.error("fail:orderId:" + bankOrder.getOrderId()+ " errcode:" + ProcCodeConstants.PROC_CODE_100E6022+ " err:bis query is null.");
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
				checkOrderResult.setErrMsg("银行返回对账结果为空");
				return checkOrderResult;
			}
			if (!"0".equals(response.getStatus().trim())) {
				logger.error("平安银行B2B对账失败，订单查询交易异常，银行返回状态不为0，status："+ response.getStatus() + ", errDesc: "+ response.getErrDesc());
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
				checkOrderResult.setErrMsg("银行订单查询交易异常");
				return checkOrderResult;
			}
			List orders = response.getOrders();
			if (orders == null) {
				logger.error("平安银行B2B对账，订单查询结果集为null，status："+ response.getStatus() + ", errDesc: "+ response.getErrDesc());
				// 能差到订单，表示银行肯定处理成功（只是不确定是否入账）。
				// 返回无数据可能银行处理失败，可能未收到订单，，可能未处理完，平台按处理中处理
				checkOrderResult.setErrMsg("银行返回对账结果为空");
				return checkOrderResult;
			}
			if (orders.size() < 1) {
				logger.error("平安银行B2B对账，订单查询结果集无数据，status："+ response.getStatus() + ", errDesc: "+ response.getErrDesc() + ", orders.size: "+ orders.size());
				// 通orders == null情况
				checkOrderResult.setErrMsg("银行返回对账结果为空");
				return checkOrderResult;
			}
			PabOrderMessageRes order = (PabOrderMessageRes) orders.get(0);
			String commitFlag = order.getCommitFlag();// 结帐标记：0=未结帐，1=结帐中，2=已结帐，3=永不结帐，5=代表等待确认
			// 成功处理
			if (PabConstants.TRAN_SDB_DEAL_CHECKOUT.equals(commitFlag) || PabConstants.TRAN_SDB_DEAL_NO_CHECK.equals(commitFlag)) {
				logger.info("平安银行B2B订单: " + bankOrder.getOrderId()+ "交易返回成功，结账标记：" + commitFlag + "，执行账务处理");
				checkOrderResult.setSuccess(true);
				InAccInfo accInfo = new InAccInfo();
				accInfo.setOrderId(bankOrder.getOrderId());
				accInfo.setAmount(BigDecimal.valueOf(response.getSum()));
				accInfo.setRetCode("00");
				accInfo.setCardType(BankCardType.Unknown.toString());
				checkOrderResult.setAccInfo(accInfo);
			}  else if(PabConstants.TRAN_SDB_DEAL_CHECK_IN.equals(commitFlag)){
				logger.error("平安银行B2B订单: " + bankOrder.getOrderId()+ "交易银行结账标记：" + commitFlag + "，未知，暂不进行账务处理");
				checkOrderResult.setErrMsg("银行返回对账结果未知");
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
				checkOrderResult.setErrMsg(PabConstants.TRAN_SDB_MESSAGE_CHECK_IN);
			}else if(PabConstants.TRAN_SDB_DEAL_DONT_CHECK.equals(commitFlag)){
				logger.error("平安银行B2B订单: " + bankOrder.getOrderId()
						+ "交易银行结账标记：" + commitFlag + "，永不结账，暂不进行账务处理");
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
				checkOrderResult.setErrMsg(PabConstants.TRAN_SDB_MESSAGE_DONT_CHECK);
			}else if(PabConstants.TRAN_SDB_DEAL_TOBE_CONFIRMED.equals(commitFlag)){
				logger.error("平安银行B2B订单: " + bankOrder.getOrderId()
						+ "交易银行结账标记：" + commitFlag + "，等待确认，暂不进行账务处理");
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
				checkOrderResult.setErrMsg(PabConstants.TRAN_SDB_MESSAGE_TOBE_CONFIRMED);
			}
			else {
				logger.error("平安银行B2B订单: " + bankOrder.getOrderId()
						+ "交易银行结账标记：" + commitFlag + "，未知，暂不进行账务处理");
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
				checkOrderResult.setErrMsg(PabConstants.TRAN_SDB_MESSAGE_NO_CHECK);
			}
			
			return checkOrderResult;
		} catch (Exception e) {
			logger.error("pab b2b bankorder fail.", e);
			checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
			checkOrderResult.setErrMsg("银行对账异常");
			return checkOrderResult;
		}
	}
	@Override
	public BankOrder getDbOrder() {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public BaseMessage dayend(String bank_bus) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public List<CheckOrderResult> checkDayend(String bank_bus) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public Result getDayendMsg(String string) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public CheckOrderResult checkDayendOrder(BaseDayendEntry bdm, BankOrder bo) {
		// TODO Auto-generated method stub
		return null;
	}
}
